Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removes SourceFilesConfiguration in favor of list of LayerConfiguration in BuildConfiguration. #516

Merged
merged 27 commits into from
Jul 25, 2018

Conversation

coollog
Copy link
Contributor

@coollog coollog commented Jul 6, 2018

Regards #480 (comment)

This is also in preparation for Jib as a library for Java.

This also fixes #622, fixes #563, and moves entrypoint to be provided to BuildConfiguration (removing mainClass and jvmFlags).

private static ImmutableList<String> getEntrypoint(
BuildConfiguration buildConfiguration, SourceFilesConfiguration sourceFilesConfiguration) {
private static ImmutableList<String> getEntrypoint(BuildConfiguration buildConfiguration) {
// TODO: Don't use indexes.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yeah this is a weird problem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be weird to split it into java and non-java layer groups?

@coollog
Copy link
Contributor Author

coollog commented Jul 19, 2018

Fixed a bunch of merge conflicts - still need to make the changes in jib-gradle-plugin and jib-maven-plugin

@coollog coollog requested a review from a team July 20, 2018 18:37
@coollog
Copy link
Contributor Author

coollog commented Jul 20, 2018

This should be good for review now - this ended up being quite large - I'll do a pass myself too

Copy link
Member

@chanseokoh chanseokoh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Briefly went through 1/3 of the code. Will look into it further.

@Rule public TemporaryFolder temporaryCacheDirectory = new TemporaryFolder();

@Rule public TemporaryFolder temporaryTarOutput = new TemporaryFolder();
@Rule public TemporaryFolder temporaryFolder = new TemporaryFolder();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it's harmless to have final. Is the repo generally lenient about final?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should definitely have final where-ever applicable and have things be non-final unless absolutely necessary.

* @param entrypoint the tokenized command to run when the container starts
* @return this
*/
public Builder setEntrypoint(@Nullable List<String> entrypoint) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the point of allowing null? Also, I think we should document the behavior: "passing null does nothing; it does not clear the previous value."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The point of allowing null is to allow for building an image without an entrypoint (since it's an optional field on the image format). This can also be useful for when we propagate base image container configuration so fields like entrypoint could be propagated. But yes, we should defintely document the behavior.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If so, why not just clear the entrypoint if null is given? That's more intuitive and what I'd expect normally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That makes a lot of sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or, actually - I think we should probably have the semantics be like:

null - if base image has entrypoint, propagate; otherwise, don't set an entrypoint
non-null - set entrypoint to what is given (empty would be empty entrypoint, etc.)

@@ -65,16 +77,23 @@ public static Builder builder() {
}

private final ImmutableList<LayerEntry> layerEntries;
private String label;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably final.

.forEach(dependencyFile -> buildLogger.info("\t\t" + dependencyFile));
for (LayerConfiguration layerConfiguration :
buildSteps.getBuildConfiguration().getLayerConfigurations()) {
buildLogger.info("\t" + capitalizeFirstLetter(layerConfiguration.getLabel()) + ":");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why capitalizing the first letter for logging? Shouldn't it be ideal to print out the label as-is? Also it'd be less of a headache if we can get out of the locale business.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mostly had this to keep the log message consistent with what it was before. We should definitely consider changing this logic to be something more configurable, but this log message will be part of the "plugins-common" rather than jib-core. There should probably be an enum from a layer type (DEPENDENCIES, CLASSES, etc.) to the intended label string and log string.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, just keep in mind you'd normally consider what locale to use if the text can be something else than English, e.g., https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#toUpperCase(java.util.Locale)

List<String> classpathElements, List<String> jvmFlags, String mainClass) {
String classpathString = String.join(":", classpathElements);

List<String> entrypointBuilder = new ArrayList<>(4 + jvmFlags.size());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels weird to call it Builder.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change this to EntrypointConstructor (like in the jib library design).

}
private String expectedDependenciesPath = "/app/libs/";
private String expectedResourcesPath = "/app/resources/";
private String expectedClassesPath = "/app/classes/";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these suitable for static final?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep!

@@ -4,6 +4,7 @@ COPY libs /app/libs/
COPY snapshot-libs /app/libs/
COPY resources /app/resources/
COPY classes /app/classes/
COPY root /
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just asking: does this open up the possibility that copying the files at root/ might overwrite existing files, or is it that root/ will never have a sub-directory called app/?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it opens up that possibility.


### Changed

- Only builds non-empty layers ([#516](https://github.com/GoogleContainerTools/jib/pull/516/files))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it true? I saw above

   // TODO: Don't generate empty layers.
   /**
    * Creates the Docker context in {@code #targetDirectory}.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's just for generating the Docker context; I don't think empty layers are added to the image itself in jib:build etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops forgot to remove that - it actually skips the empty layers now.

Copy link
Contributor

@TadCordle TadCordle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Halfway done, will get to the rest later.

@@ -42,25 +49,36 @@
/** Integration tests for {@link BuildSteps}. */
public class BuildStepsIntegrationTest {

/** Lists the files in the {@code resourcePath} resources directory. */
private static ImmutableList<Path> getFilesList(String resourcePath)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is specifically for resources maybe it should be renamed to getResourceFilesList.

.build());
buildImageSteps.run();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we running this 3 times now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops, removing.


switch (errorMessages.size()) {
case 0: // No errors
if (baseImageReference == null || targetImageReference == null || mainClass == null) {
if (baseImageReference == null || targetImageReference == null) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we error if entrypoint is empty like we used to error when mainClass was null?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm intending it to be possibly be empty to allow for propagation of entrypoint from base images in the future (when this is used as a library).

private ImmutableMap<String, String> environmentMap = ImmutableMap.of();
private ImmutableList<Port> exposedPorts = ImmutableList.of();
private Class<? extends BuildableManifestTemplate> targetFormat = V22ManifestTemplate.class;
@Nullable private CacheConfiguration applicationLayersCacheConfiguration;
@Nullable private CacheConfiguration baseImageLayersCacheConfiguration;
private boolean allowHttp = false;
@Nullable private LayerConfiguration extraFilesLayerConfiguration;
private ImmutableList<LayerConfiguration> layerConfigurations = ImmutableList.of();
private ImmutableList<String> entrypoint = ImmutableList.of();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very much a nit, so feel free to ignore, but for organization it'd be nice to put entrypoint next to javaArguments instead of at the end.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This same ordering happens in a bunch of other places too, but I didn't want to overload the comments.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, maybe we can leave that to another PR that can set up a nice ordering pattern for all of these parameters.


@Nullable private String baseImage;
private List<String> jvmFlags = Collections.emptyList();
private String mainClass = "";
private List<String> javaArguments = Collections.emptyList();
private List<String> exposedPorts = Collections.emptyList();

public DockerContextGenerator(SourceFilesConfiguration sourceFilesConfiguration) {
this.sourceFilesConfiguration = sourceFilesConfiguration;
// TODO: Just take the LayerConfigurations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be that difficult to just do this now? I think we should avoid adding TODOs while trying to fix other issues.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into that again, but the main issue is that since this is in jib-core, it doesn't know what layer label corresponds to which copy directive.

@@ -114,6 +180,7 @@ public DockerContextGenerator setExposedPorts(List<String> exposedPorts) {
return this;
}

// TODO: Don't generate empty layers.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

@@ -166,6 +156,13 @@ private static void handleRegistryUnauthorizedException(
}
}

private static String capitalizeFirstLetter(String string) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use StringUtils#capitalize() instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to avoid having to add the Apache Commons library just for this function, and preferring Guava over Apache Commons.

@@ -198,7 +179,7 @@ public void testBuilder_missingValues() {

} catch (IllegalStateException ex) {
Assert.assertEquals(
"base image is required but not set, target image is required but not set, and main class is required but not set",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I think we should keep a test for the default case of having 3 or more error messages. Or we can just delete that default case logic since we only have two possible error messages at the moment (missing target and missing base).

@@ -9,6 +9,15 @@ All notable changes to this project will be documented in this file.

### Fixed

## 0.9.8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't these still be under unreleased?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, oops.

Copy link
Contributor

@TadCordle TadCordle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other than that LGTM, should file issues for the new TODOs.

@coollog
Copy link
Contributor Author

coollog commented Jul 25, 2018

Trying to fix an integration test on this, will merge after that is fixed.

TODOs have been filed too.

@coollog
Copy link
Contributor Author

coollog commented Jul 25, 2018

Ah looks like it was just timing out when pulling the image because I am on a slow internet.

@coollog coollog merged commit 6bf0148 into master Jul 25, 2018
@coollog coollog deleted the no-sourcefilesconfiguration branch July 25, 2018 15:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Do not add empty layers to image. Export extra files layer in Docker context.
4 participants